#pragma once


#ifndef _UDP_SEVER_HPP
#define _UDP_SEVER_HPP

#include<iostream>
#include<string>
#include<memory>
#include<cstring>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include"log.hpp"

class UdpSever
{
public:
    UdpSever(uint16_t port, std::string ip ) :_port(port), _ip(ip)
    {}

    bool InitSever()
    {
        //创建套接字
        _sock = socket(AF_INET, SOCK_DGRAM, 0);

        struct sockaddr_in local ;
        bzero(&local, sizeof local);
        //memset(&local, 0, sizeof local);
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = _ip.empty() ? INADDR_ANY : inet_addr(_ip.c_str());

        //绑定
        if(bind(_sock, (struct sockaddr*)&local, sizeof local) < 0)
        {
            logMessage(FATAL, "%d-%s", errno, strerror(errno));
            exit(1);
        }
        logMessage(NORMAL, "init udp server done ... %s", strerror(errno));
        return true;
    }

    bool Start()
    {
        char buff[1024];

        while(1)
        {
            struct sockaddr_in peer;
            bzero(&peer, sizeof peer);
            
            socklen_t len = sizeof(peer);

            ssize_t s = recvfrom(_sock, buff, sizeof (buff) - 1, 0, (struct sockaddr*)&peer, &len);
            if(s > 0)
            {
                uint16_t cli_port = ntohs(peer.sin_port);
                std::string cli_ip = inet_ntoa(peer.sin_addr);
                printf("[%s : %d]# %s\n", cli_ip.c_str(), cli_port, buff);
                sendto(_sock, buff, sizeof buff, 0, (struct sockaddr*)&peer, len);
            }
        }
    }

    ~UdpSever()
    {}

private:
    uint16_t _port;
    std::string _ip;
    int _sock;

};

#endif